package online.heycm.rbac.common.app;

import online.heycm.platform.log.Logger;
import online.heycm.platform.log.LoggerManager;
import online.heycm.rbac.common.cache.DictionaryCache;
import online.heycm.rbac.common.cache.InterfaceCache;
import online.heycm.rbac.common.cache.ParamCfgCache;
import online.heycm.rbac.common.cache.RoleCache;
import online.heycm.rbac.common.cache.RolePermitCache;
import online.heycm.rbac.common.entity.InterfaceDef;
import online.heycm.rbac.common.entity.RolePermitDef;
import online.heycm.rbac.domain.basic.repository.DictionaryRepository;
import online.heycm.rbac.domain.basic.repository.ParamCfgRepository;
import online.heycm.rbac.domain.basic.repository.RbacRepository;
import online.heycm.rbac.domain.basic.repository.entity.BasicDictionary;
import online.heycm.rbac.domain.basic.repository.entity.BasicParamCfg;
import online.heycm.rbac.domain.basic.repository.entity.BasicRbacInterface;
import online.heycm.rbac.domain.basic.repository.entity.BasicRbacRole;
import online.heycm.rbac.domain.basic.repository.entity.BasicRbacRoleInterface;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map.Entry;
import java.util.stream.Collectors;

/**
 * 启动监听，初始化缓存
 *
 * @author heycm
 * @since 2024/1/14 15:47
 */
@Component
public class AppRunner implements ApplicationRunner {

    private static final Logger log = LoggerManager.getLogger(AppRunner.class);

    @Autowired
    private RbacRepository rbacRepository;

    @Autowired
    private DictionaryRepository dictionaryRepository;

    @Autowired
    private DictionaryCache dictionaryCache;

    @Autowired
    private ParamCfgRepository paramCfgRepository;

    @Autowired
    private ParamCfgCache paramCfgCache;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        // 角色缓存
        startupRoleCache();
        // 字典缓存
        startupDictionaryCache();
        // 配置缓存
        startupParamCfgCache();
        // 接口缓存
        startupInterfaceCache();
        // 角色接口权限缓存
        startupRolePermitCache();
    }

    private void startupRolePermitCache() {
        log.info("角色权限缓存开始");
        List<BasicRbacRoleInterface> rfs = rbacRepository.allRoleInterfaces();
        List<RolePermitDef> defs = rfs.stream().map(r -> {
            RolePermitDef def = new RolePermitDef();
            def.setRoleId(r.getRoleId());
            def.setInterfaceId(r.getInterfaceId());
            return def;
        }).collect(Collectors.toList());
        for (Entry<String, BasicRbacRole> entry : RoleCache.getAllCache().entrySet()) {
            RolePermitCache.update(entry.getKey(), defs.stream().filter(def -> entry.getValue().getRoleId().equals(def.getRoleId())).collect(Collectors.toList()));
        }
        log.info("角色权限缓存完成");
    }

    private void startupInterfaceCache() {
        log.info("接口缓存开始");
        List<BasicRbacInterface> interfaces = rbacRepository.allInterfaces();
        List<InterfaceDef> defs = interfaces.stream().map(i -> {
            InterfaceDef def = new InterfaceDef();
            def.setId(i.getInterfaceId());
            def.setPath(i.getInterfacePath());
            def.setNeedToken(i.getNeedToken());
            return def;
        }).collect(Collectors.toList());
        InterfaceCache.updateAll(defs);
        log.info("接口缓存完成, 缓存: {}行", defs.size());
    }

    private void startupParamCfgCache() {
        log.info("配置缓存开始");
        List<BasicParamCfg> paramCfgs = paramCfgRepository.list();
        paramCfgCache.updateAll(paramCfgs);
        log.info("配置缓存完成, 缓存: {}行", paramCfgs.size());
    }

    private void startupDictionaryCache() {
        log.info("字典缓存开始");
        List<BasicDictionary> dictionaries = dictionaryRepository.list();
        dictionaryCache.updateAll(dictionaries);
        log.info("字典缓存完成, 缓存: {}行", dictionaries.size());
    }

    private void startupRoleCache() {
        log.info("角色缓存开始");
        List<BasicRbacRole> roles = rbacRepository.allRoles();
        RoleCache.updateAll(roles);
        log.info("角色缓存完成, 缓存: {}行", roles.size());
    }
}
